package com.siyoumi.console.modules.sys.service;

import com.siyoumi.component.XRedis;
import com.siyoumi.component.XApp;
import com.siyoumi.util.XLog;
import com.siyoumi.util.XStr;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

@Slf4j
public class CmdThread
        extends Thread {
    private final String cmd; //命令
    //redis key 用于获取返回内容
    private final String redisKey;

    //执行结束
    @Getter
    private boolean readFinish = false;
    //执行中
    @Getter
    private boolean ready = false;


    public CmdThread(String key, String cmd) {
        this.redisKey = key;
        this.cmd = cmd;
    }

    @SneakyThrows
    public void run() {
        InputStreamReader inputSr = null;
        BufferedReader inputBr = null;
        Process process = null;
        try {
            String charset = "UTF-8";
            String shell = "sh -c " + cmd;
            if (XApp.isWindows()) {
                charset = "GBK";
                shell = "cmd.exe /c " + cmd;
            }

            XLog.info(this.getClass(), shell);

            process = Runtime.getRuntime().exec(shell);
            inputSr = new InputStreamReader(process.getInputStream(), charset);
            inputBr = new BufferedReader(inputSr);

            log.info("命令开始执行");
            String line = null;
            int max = 2000; //最大执行次数
            while (max > 0) {
                if (!ready) {
                    //有输出，才算开始
                    ready = inputBr.ready();
                }

                if (ready) {
                    if ((line = inputBr.readLine()) != null) {
                        log.info("{}:" + line, max);
                        if (XStr.hasAnyText(line)) {
                            XRedis.getBean().lPush(redisKey, line);
                        }
                    } else {
                        break;
                    }
                } else {
                    log.info("{}:", max);
                }

                Thread.sleep(200);
                max--;
            }
        } catch (IOException | InterruptedException ioe) {
            ioe.printStackTrace();
            log.info("正式执行命令：有IO异常");
        } finally {
            try {
                if (process != null) {
                    process.destroy();
                }
                if (inputBr != null) {
                    inputBr.close();
                }
                if (inputSr != null) {
                    inputSr.close();
                }
            } catch (IOException ioe) {
                ioe.printStackTrace();
                log.info("正式执行命令：有IO异常");
            }
            log.info("命令已执行完成");
            XRedis.getBean().lPush(redisKey, "执行完成");
            readFinish = true;
        }
    }
}
